

import crypto from 'crypto';
import fs from 'fs';
import { Controller, GET, POST } from 'fastify-decorators';
import { FastifyReply, FastifyRequest } from 'fastify';
import puppeteerService from '../service/puppeteer.service';
import { z } from 'zod';
import { app } from '..';
import { PUBLIC_PATH, TMP_PATH } from '../config/env';
import dayjs from 'dayjs';
import { Prisma, UserApiCall } from '@prisma/client';
import userService from '../service/user.service';


@Controller({ route: '/screenshot' })
export default class PuppeteerController {
    getPageCaptureSchema = z.object({
        url: z.string(),
        token: z.string(),
        device: z.string().default('pc'),
        pixel: z.number().default(1),
        captureSize: z.string().default('firstScreen')
    });


    @GET({ url: '/content' })
    async getPageContent(request: FastifyRequest, reply: FastifyReply) {
        const { url } = z.object({ url: z.string() }).parse(request.query);
        const res = await puppeteerService.getPageContent(url);
        return app.json(res);
    }

    @POST({ url: '/capture' })
    async getPageCapture(request: FastifyRequest, reply: FastifyReply) {
        const { url, token, ...options } = this.getPageCaptureSchema.parse(request.body);
        const ret = await app.prisma.$transaction(async (tx) => {
            const userToken = await tx.userToken.findFirst({ where: { token }, include: { user: true } });
            if (!userToken) {
                throw new Error('token error');
            }

            const user = userToken.user;
            const isFreeUser = await userService.isFree(user);
            if (isFreeUser && user.callCount <= 0) {
                throw new Error('not has count');
            }
            // 剩余次数 -1
            if (isFreeUser) {
                await tx.user.update({ data: { callCount: user.callCount - 1 }, where: { id: user.id } });
            }

            // 创建记录
            const userApiCallData: Prisma.UserApiCallUncheckedCreateInput = {
                userId: user.id,
                tokenId: userToken.id,
                targetUrl: url,
                targetParams: JSON.stringify({})
            };
            await tx.userApiCall.create({ data: userApiCallData });

            // 调用service获取截图
            const buf = await puppeteerService.getPageCapture(url, options);
            return reply.type('image/jpeg').send(buf);
        });
        return ret;
    }

    @GET({ url: '/statistic' })
    async get(request: FastifyRequest, reply: FastifyReply) {
        const list = await app.prisma.userApiCall.findMany({ where: { userId: +request.user.id } });
        const userApiCallList = list.reduce<{ [key: string]: UserApiCall[] }>((acc, item) => {
            const date = dayjs(item.created_at).format('YYYY-MM-DD');
            if (!acc[date]) {
                acc[date] = [];
            }
            acc[date].push({ ...item, created_at: date as any });
            return acc;
        }, {});
        return app.json(userApiCallList);
    }
}
